Пусть `(u,v)` будут фиксированы. Как правило, кто-то заинтересован в вычисления всех частных производных `S(u,v)`, вплоть до степени `d`, то есть
`∂^(k+l)/(∂^k u∂^l v) S(u,v)` `0≤k+l≤d`(3.16)
Что касается кривых, получаем эти производные от вычисления производных базисных функций (смотри формулы [2.9] и [2.10], и Алгоритм A2.3). В частности
`∂^(k+l)/(∂^k u∂^l v)S(u,v)=sum_(i=0)^nsum_(j=0)^mN_(i,p)^((k))(u_0)N_(j,q)^((l))(v)P_(i,j)` (3.17)
Алгоритм A3.6 вычисляет точку на B-сплайн поверхности и всех частные производные, вплоть до порядк `d` (`d>p`, `q` разрешена). Аналогично Алгоритму A3.5, это пятиступенчатый процесс, на последней стадии выполняется умножение вектор/матрица/вектор вида
`∂^(k+l)/(∂^k u ∂^l v) S(u,v)=[N_(r,p)^((k)) (u)]^T [P_(r,s) ][N_(s,q)^((l)) (v)]`
`0≤k+l≤d` `uspan-p≤r≤uspan` `vspan-q≤s≤vspan` (3.18)
Выход это массив SKL[][], где SKL[k][l] производная `S(u,v)` по отношению к `u` `k` раз, и `v` `l` раз. При фиксированном `k`, `0≤k≤d`, локальный массив temp[] хранит результирующий вектор/матрицу, `[N_(r,p)^((k)) (u)]^T [P_(r,s) ]`, пока умножается на `[N_(s,q)^((l)) (v)]`, при `0≤l≤d-k`. Массивы Nu[][] и Nv[][] используются для хранения производных базисных функций.SurfaceDerivsAlg1(n,p,U,m,q,V,P,u,v,d,SKL) { /* Вычислить производные поверхности */ /* Вход: n,p,U,m,q,v,P,u,v,d */ /* Выход: SKL */ du = min(d,p); for (k=p+1; k<=d; k++) for (l=0; l<=d-k; l++) SKL[k][l] = 0.0; dv = min(d,q); for (l=q+1; l<=d; l++) for (k=0; k<=d-l; k++) SKL[k][l] = 0.0; uspan = FindSpan(n,p,u,U); DersBasisFuns(uspan,u,p,du,U,Nu); vspan = FindSpan(m,q,v,V); DersBasisFuns(vspan,v,q,dv,V,Nv); for (k=0; k<=du; k++) { for (s=0; s<=q; s++) { temp[s] = 0.0; for (r=0; r<=p; r++) temp[s] = temp[s] + Nu[k][r]*P[uspan-p+r][vspan-q+s]; } dd = min(d-k,dv); for (l=0; l<=dd; l++) { SKL[k][l] = 0.0; for (s=0; s<=q; s++) SKL[k][l] = SKL[k][l] + Nv[l][s]*temp[s]; } } }Обратите внимание, что производные уменьшены на 1⁄2 для лучшей визуализации.
Рисунок 3.26. Бикубическая поверхность, определенная для `U=V={0,0,0,0,`1⁄2,`1,1,1,1}` и ее первая и вторая частные производные, вычисленные при `u=`3⁄4 и `v=`2⁄5.
Давайте формально дифференцировать `S(u,v)`. Что касается `u`, мы имеем
`S_u (u,v)=∂/∂u S(u,v)=sum_(j=0)^mN_(j,q)(v)(∂/∂u sum_(i=0)^nN_(i,p)(u)P_(i,j))=sum_(j=0)^mN_(j,q)(v)(∂/∂u C_j(u))`(3.19)
где `C_j(u)=sum_(i=0)^nN_(i,p)(u)P_(i,j)` `j=0,…,m`
кривые B-сплайна. Применяя формулу (3.6) для каждого из `C_j(u)` и подставляя в уравнение (3.19), получаем`S_u(u,v)=sum_(i=0)^(n-1)sum_(j=0)^mN_(i,p-1)(u)N_(j,q)(v)P_(i,j)^{(1,0)}` (3.20)
где `P_(i,j)^((1,0))=p(P_(i+1,j)-P_(i,j))/(u_(i+p+1)-u_(i+1))` (смотри уравнение [3.4])
`U^((1))="{"ubrace(0,…,0)_p,u_(p+1),…,u_(r-p-1),ubrace(1,…,1)_p"}"`
`V^((0))=V`
Аналогично `S_v(u,v)=sum_(i=0)^nsum_(j=0)^(m-1)N_(i,p)(u)N_(j,q-1)(v)P_(i,j)^{(0,1)}`(3.21)
где `P_(i,j)^((0,1))=p(P_(i,j+1)-P_(i,j))/(u_(j+q+1)-u_(j+1))`
`U^((0))=U`
`V^((1))="{"ubrace(0,…,0)_q,u_(q+1),…,u_(s-q-1),ubrace(1,…,1)_q"}"`
Применения первое уравнение (3.20), то из уравнения (3.21) следует
`S_{uv}(u,v)=sum_(i=0)^(n-1)sum_(j=0)^(m-1)N_(i,p-1)(u)N_(j,q-1)(v)P_(i,j)^{(1,1)}` (3.22)
где `P_(i,j)^((1,1))=p(P_(i,j+1)^((1,0))-P_(i,j)^((1,0)))/(u_(j+q+1)-u_(j+1))`
и `U^((1))` и `V^((1))` являются такими, как определено ранее.В целом
`∂^(k+l)/(∂^k u ∂^l v)S(u,v) =sum_(i=0)^(n-k)sum_(j=0)^(m-l)N_(i,p-k)(u_0)N_(j,q-l)(v)P_(i,j)^{(k,l)}` (3.23)
где `P_(i,j)^((k,l))=p(P_(i,j+1)^((k,l-1))-P_(i,j)^((k,l-1)))/(u_(j+q+1)-u_(j+l))`
Используя формулы (3.20) - (3.23), мы получаем полезные формулы для производных угловых узлов. Например, в угловом узле `(u,v)=(0,0)`, имеем
`S_u(0,0)=P_{0,0}^{(1,0)}=p/u_(p+1)(P_{1,0}-P_{0,0})`
`S_v(0,0)=P_{0,0}^{(0,1)}=q/v_(q+1)(P_{0,1}-P_{0,0})`(3.24)
`S_{uv}(0,0)=P_{0,0}^{(1,1)}=q/v_(q+1)(P_{0,1}^{(1,0)}-P_{0,0}^{(1,0)})=pq/(u_(p+1)v_(q+1))(P_{1,1}-P_{0,1}-P_{1,0}+P_{0,0})`
Теперь пусть `u_0=0` и `v_0=0` . Из свойств базисных функций, легко видеть, что изокривые `C_(u_0)(v)` и `C_(v_0)(u)` задаются`C_(u_0)(v)=sum_(j=0)^mN_(j,q)(v)P_(0,j)` `C_(v_0)(u)=sum_(i=0)^nN_(i,p)(u)P_(i,0)`
Из уравнения (3.7) следует, что`S_u(0,0)=C_(v_0)^'(0)` `S_v(0,0)=C_(u_0)^'(0)`
Алгоритм A3.7 вычисляет все (или, опционально, некоторые) из контрольных точек, `P_(i,j)^{(k,l)}`, из производных поверхностей до порядка `d` (`0≤k+l≤d`). Алгоритм основан на уравнении (3.23) и Алгоритме A3.3. Выход массив PKL[][][][], где PKL[k][l][i][J] является контрольной точкой `i,j`-ой поверхности, дифференцированные `k` раз, в отношении `u` и `l` раз по отношению к `v`.
SurfaceDerivCpts(n,p,U,m,q,V,P,d,r1,r2,s1,s2,PKL) { /* Вычислить контрольные точки производных поверхностей */ /* Вход: n,p,U,m,q,V,P,d,r1,r2,s1,s2 */ /* Выход: PKL */ du = min(d,p); dv = min(d,q); r = r2 - r1; s = s2 - s1; for (j=s1; j<=s2; j++) { CurveDerivCpts(n,p,U,&P[][j],du,r1,r2,temp); for (k=0; k<=du; k++) for (i=0; i<=r-k; i++) PKL[k][0][i][j-s1] = temp[k][i]; } for (k=0; k<du; k++) for (i=0; i<=r-k; i++) { dd = min(d-k,dv); CurveDerivCpts(m,q,&V[s1],&PKL[k][0][i][],dd,0,s,temp); for (1=1; l<=dd; 1++) for (j=0; j<=s-l; j++) PKL[k][l][i][j] = temp[l][j]; } }
Алгоритм A3.8 вычисляет точку на B-сплайн поверхности и все частные производные до и включая порядка `d`: по фиксированным параметрам `(u,v)` (сравните с Алгоритмом A3.6). `d>p`, `q` допускается. На выходе SKL[k][l] производная `S(u,v)` `k` раз по `u` и `l` раз по `v`.
SurfaceDerivsAlg2(n,p,U,m,q,V,P,u,v,d,SKL) { /* Вычислить производные поверхности */ /* Вход: n,p,U,m,q,v,P,u,v,d */ /* Выход: SKL */ du = min(d,p); for (k=p+1; k<=d; k++) for (l=0; l<=d-k; l++) SKL[k][l] = 0.0; dv = min(d,q); for (l=q+1; l<=d; l++) for (k=0; k<=d-l; k++) SKL[k][l] =0.0; uspan = FindSpan(n,p,u,U); AllBasisFuns(uspaa,u,p,U,Nu); vspan = FindSpan(m,q,v,V); AllBasisFuns(vspan,v,q,V,Nv); SurfaceDerivCpts(n,p,U,m,q,V,P,d,uspan-p,uspan,vspan-q,vspan,PKL); for (k=0; k<=du; k++) { dd = min(d-k,dv); for (l=0; l<=dd; l++) { SKL[k][l] = 0.0; for (i=0; i<=q-l; i++) { tmp = 0.0; for (j=0; j<=p-k; j++) tmp = tmp + Nu[j][p-k]*PKL[k][l][j][i]; SKL[k][l] = SKL[k][l] + Kv[i][q-l]*tmp; } } } }
Упражнения
где `U={0,0,0,`1⁄2,`1,1,1}`
`V={0,0,0,1,1,1}`
и `P_{0,0}=(0,0,0)` `P_{1,0}=(3,0,3)` `P_{2,0}=(6,0,3)` `P_{3,0}=(9,0,0)`
`P_{0,1}=(0,2,2)` `P_{1,1}=(3,2,5)` `P_{2,1}=(6,2,5)` `P_{3,1}=(9,2,2)`
`P_{0,2}=(0,4,0)` `P_{1,2}=(3,4,3)` `P_{2,2}=(6,4,3)` `P_{3,2}=(9,4,0)`
Вычислите `S`(3⁄10,6⁄10), оценивая ненулевые базисные функции B-сплайна и умножая их на соответствующие контрольные точки.